async function customAlert(message) {
    await Swal.fire({
        text: message,
        icon: 'info',
        confirmButtonText: '确定'
    });

    // 模拟点击确定：$(".swal2-confirm").click();
}

async function customConfirm(message) {
    const result = await Swal.fire({
        text: message,
        icon: 'question',
        showCancelButton: true,
        confirmButtonText: '确定',
        cancelButtonText: '取消'
    });
    return result.isConfirmed;
}

async function customPrompt(message, inputType = 'text', inputPlaceholder = '') {
    const { value: result } = await Swal.fire({
        title: message,
        input: inputType,
        inputPlaceholder: inputPlaceholder,
        showCancelButton: true,
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        inputValidator: (value) => {
            if (!value) {
                return '你需要输入一些内容！';
            }
        }
    });

    if (result !== undefined) {
        return result;
    } else {
        return null; // 表示取消
    }
}

function shuffle(array) {
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]]; // 交换元素
    }
    return array;
}

function getRandomCards(cards, num = 7) {
    const keys = Object.keys(cards);
    const shuffled = shuffle(keys);
    return shuffled.slice(0, num).map(key => cards[key]);
}

function hasSubstatus(status) {
    return window.actionData.substatus.includes(status);
}

function countOfRooms() {
    const extraRooms = window.myData.minorDevelopmentCards.filter(card => card.extraRooms !== undefined).reduce((sum, card)=> {
        return sum + card.extraRooms;
    }, 0);
    return extraRooms + window.myData.farmCells.flat().filter(cell => cell.building === "woodenHut" || cell.building === "clayHut" || cell.building === "stoneHouse").length;
}

function appendWorkerToTitle(workSpaceId) {
    // 在标题后追加工人的显示
    var node = $("#" + workSpaceId + " .work-space-title");
    node.append($('<span class="your-worker">(人)</span>'));

    window.myData.workersWorkspaces.push(workSpaceId);
}

function updateResourceBar() {
    var data = window.myData;
    var str = `
        <p>木材:&nbsp;${data.wood}&nbsp;&nbsp;&nbsp;
            泥块:&nbsp;${data.clay}&nbsp;&nbsp;&nbsp;
            芦苇:&nbsp;${data.reed}&nbsp;&nbsp;&nbsp;
            石块:&nbsp;${data.stone}&nbsp;&nbsp;&nbsp;
            小麦:&nbsp;${data.grain}
        </p>
        <p>
            蔬菜:&nbsp;${data.vegetable}&nbsp;&nbsp;&nbsp;
            食物:&nbsp;${data.food}&nbsp;&nbsp;&nbsp;
            剩余栅栏:&nbsp;${data.leftFences}&nbsp;&nbsp;&nbsp;
            剩余畜棚:&nbsp;${data.leftStables}
        </p>
        <p>
            总工人数:&nbsp;${data.totalWorkers}&nbsp;(婴儿:&nbsp;${data.newborns.length})
            未使用工人:&nbsp;${data.unusedWorker}&nbsp;&nbsp;&nbsp;
        </p>
        <p>
            劣势:&nbsp;${data.disadvantages}&nbsp;&nbsp;&nbsp;
            已获得分数:&nbsp;${data.score ?? 0}
        </p>
    `
    $(".resource-bar").empty();
    $(".resource-bar").append($(str));
}

function updateFarm() {
    for (let i = window.myData.farmCells.length - 1; i >= 0; i--) {
        const colunm = window.myData.farmCells[i];
        for (let j = colunm.length - 1; j >= 0; j--) {
            const cell = colunm[j];
            var str = ""
            if (cell.building != null) {
                switch (cell.building) {
                    case "field":
                        str += `农田`;
                        break;
                    case "woodenHut":
                        str += `木屋`;
                        break;
                    case "clayHut":
                        str += `砖房`;
                        break;
                    case "stoneHouse":
                        str += `石屋`;
                        break;
                    case "stable":
                        str += `畜棚`;
                        break;
                    default:
                        break;
                }
            }
            if (cell.sheep > 0) {
                str += `${str.length > 0 ? " " : ""}羊：${cell.sheep}`;
            }
            if (cell.pig > 0) {
                str += `${str.length > 0 ? " " : ""}猪：${cell.pig}`;
            }
            if (cell.cattle > 0) {
                str += `${str.length > 0 ? " " : ""}牛：${cell.cattle}`;
            }
            if (cell.grain > 0) {
                str += `${str.length > 0 ? " " : ""}麦：${cell.grain}`;
            }
            if (cell.vegetable > 0) {
                str += `${str.length > 0 ? " " : ""}蔬：${cell.vegetable}`;
            }
            $(`.farm-y${j} .farm-x${i}`).text(str);
        }
    }

    updateAnimalButtonsVisibility();
    updatePastures();
}

var allPromptViews = null;

function initAllPromptViews() {
    if (allPromptViews == null) {
        allPromptViews = {
            "buildRooms": {
                class: ".build-rooms-prompt-view",
                func: updatePromptViewForBuildingRoomsOrStables,
            },
            "plowingFields": {
                class: ".plowing-fields-prompt-view"
            },
            "buildingFences": {
                class: ".building-Fences-prompt-view"
            },
            "moveAnimal": {
                class: ".move-animal-prompt-view"
            },
            "moveSingleAnimal": {
                class: ".move-animal-prompt-view"
            },
            "removeAnimal": {
                class: ".remove-animal-prompt-view"
            },
            "grainUtilization": {
                class: ".grain-utilization-prompt-view"
            },
            "farming": {
                class: ".farming-prompt-view"
            },
            "farmRenovation": {
                class: ".farm-renovation-prompt-view"
            },
            "developmentCard": { // 发展卡轮次牌
                class: ".major-development-card",
                func: updateMajorDevelopmentPromptView,
            },
            "developmentCardAction": { // “主要/次要发展卡”行动，有些牌会使玩家获得这种额外行动。
                class: ".major-development-card",
                func: updateMajorDevelopmentPromptView,
            },
            "displayMajorDevelopmentCard": { // 显示主要发展卡
                class: ".major-development-card",
                func: updateMajorDevelopmentPromptViewForDisplay,
            },
            "feedingPhase": {
                class: ".feeding-phase-view",
                func: updateFeedingPhaseView,
            },
            "finalScore": {
                class: ".final-score-view"
            },
            "beforeFinalScore": {
                class: ".before-final-score-view"
            },
            "occupationTraining": {
                class: ".occupation-training-prompt-view",
                func: updateOccupationTrainingView,
            },
            "playMinorDevelopmentCard": {
                class: ".play-minor-development-view",
            },
            "bakeBread":{
                class: ".bake-bread-prompt-view",
            },
            "sowingSeeds":{ // 用于卡牌奖励的额外的播种行动
                class: ".sowing-seeds-prompt-view",
            }
        };
    }
}

function updateAdditionalView() {
    const views = allPromptViews;

    var status = window.actionData.status;

    // 隐藏所有视图
    for (let key in views) {
        $(views[key].class).css("display", "none");
    }
    $(".work-space").css("display", "none");

    // 显示对应的视图，并调用额外的方法（如果有）
    if (status && views[status]) {
        $(views[status].class).css("display", "block");
        if (views[status].func) {
            views[status].func();
        }
        pageScrollToTop();
    } else {
        $(".work-space").css("display", "block");
    }

    // 其他状态下，隐藏移动动物按钮
    updateAnimalButtonsVisibility();
}

function updateFutureRoundRewards() {
    // 获取当前轮次
    const currentRound = window.boardData.currentRound;

    // 过滤出未来轮次的资源奖励
    const futureRoundRewards = window.myData.roundRewards.slice(currentRound).map((reward, index) => {
        // 由于数组是从0开始的，所以需要加1来匹配实际的轮次编号
        const roundNumber = currentRound + index + 1;
        return { roundNumber, reward };
    }).filter(({ reward }) => Object.keys(reward).length > 0); // 过滤掉没有奖励的轮次

    // 清除旧的奖励展示
    $('.future-rewards').empty();

    // 如果没有未来轮次的奖励，则隐藏展示区域
    if (futureRoundRewards.length === 0) {
        $('.future-rewards-container').hide(); // 隐藏容器
    } else {
        // 否则，显示展示区域，并展示未来的资源奖励
        $('.future-rewards-container').show(); // 显示容器

        // 展示未来的资源奖励
        futureRoundRewards.forEach(({ roundNumber, reward }) => {
            const rewardElements = Object.entries(reward)
                .map(([resource, amount]) => `${TypeFullName[resource]}: ${amount}`)
                .join(', ');

            const rewardElement = $('<div>')
                .text(`第${roundNumber}轮：${rewardElements}`);
            $('.future-rewards').append(rewardElement);
        });
    }
}

// 用于在接下来的X轮中执行某个操作(在接下来的X张轮次牌上放置资源等)
// 返回值为 这个操作执行了多少轮，由于最大轮数只有14轮，所以可能会少于指定的rounds
function operateRoundRewardsForNextXRounds(rounds, action) {
    const currentRound = window.boardData.currentRound;
    if (currentRound == 14) {
        return 0;
    }
    var applyRoundCount = rounds;
    for (let i = 1; i <= rounds; i++) {
        const roundIndex = currentRound + i - 1;
        if (roundIndex >= window.myData.roundRewards.length) {
            break;
        }
        action(roundIndex);
        applyRoundCount = i;
    }

    updateFutureRoundRewards();

    return applyRoundCount;
}

function getCellNode(x, y) {
    return $(`.farm-y${y} .farm-x${x}`)
}

function showSelectionDialog(title, options, callback, showCancelButton = true) {
    // 创建遮罩层
    let mask = `<div id="mask" class="mask-layer"></div>`;
    $("body").append(mask);

    // 创建对话框
    let dialogHtml = `<div id="selection-dialog" class="selection-dialog">
                        <h3>${title}</h3>`;
    options.forEach(option => {
        dialogHtml += `<button class="select-button" data-value="${option.value}">${option.label}</button>`;
    });
    if (showCancelButton) {
        dialogHtml += '<button class="cancel-button">取消</button>';
    }
    dialogHtml += '</div>';

    $("body").append(dialogHtml);

    // 禁用背景点击
    $("#mask").on("click", function() {
        // 防止遮罩层被点击关闭
    });

    $(".selection-dialog .select-button").on("click", function() {
        const selectedValue = $(this).data("value");
        $("#selection-dialog").remove();
        $("#mask").remove();
        callback(selectedValue);
    });

    $(".selection-dialog .cancel-button").on("click", function() {
        $("#selection-dialog").remove();
        $("#mask").remove();
    });
}

// 弹出选择资源对话框
async function showResourceSelectionDialog(title, resources) {
    return new Promise((resolve) => {
        const options = resources.map(resource => ({
            value: resource,
            label: `${TypeFullName[resource]}`
        }));
        showSelectionDialog(title, options, resolve, false);
    });
}

function pageScrollToTop() {
    setTimeout(()=>{
        window.scrollTo({ top: 0, behavior: 'smooth' });
    }, 1);
}

function isHarvestRound(round) {
    return [4, 7, 9, 11, 13, 14].includes(round);
}

// 计算第[round]轮经历过多少次收获时节
function getHarvestTimes(round) {
    let harvestTimes = 0;
    for (let i = 1; i <= round; i++) {
        if (isHarvestRound(i)) {
            harvestTimes++;
        }
    }
    return harvestTimes;
}

function endAction() {
    window.actionData.status = null;
    window.actionData.substatus = [];

    updateAdditionalView();
    updateResourceBar();
}

// 入栈当前状态，等待新状态的流程结束
async function pushStatusAndWaitNewStatus(startNewStatusProcess) {
    await new Promise((resolve) => {
        // 暂存当前状态
        let statusStack = window.actionData.statusStack;
        statusStack.push({
            status: window.actionData.status,
            substatus: window.actionData.substatus,
            resolve
        });

        if (startNewStatusProcess) {
            startNewStatusProcess();
        }
    });
}

// 出栈并恢复状态，或者 （如果栈为空时）直接结束流程
function popStatusOrEndAction() {
    let statusStack = window.actionData.statusStack;
    if (statusStack.length > 0) {
        const statusItem = statusStack.pop();
        window.actionData.status = statusItem.status;
        window.actionData.substatus = statusItem.substatus;

        if (window.actionData.status == null) {
            updateAdditionalView();
        }
        
        if (statusItem.resolve) {
            statusItem.resolve();
        }
    } else {
        endAction();
    }
}

//------------ 交换资源为食物
function exchange(resourceType, rate) {
    // 创建确认信息
    var confirmMessage = `确定要用1${TypeName[resourceType]}换取${rate}食物吗？`;
    
    // 如果用户不确认交换，则直接返回，取消操作
    if (!confirm(confirmMessage)) {
        console.log("交换操作已取消。");
        return;  // 提前返回，不执行下面的代码
    }

    console.log(`1${resourceType} -> ${rate}食`);
    window.myData[resourceType] -= 1;
    window.myData.food += rate;

    // 如果交换的是动物，从农场中减少相应的动物数量
    var stop = false;
    if (resourceType === 'sheep' || resourceType === 'pig' || resourceType === 'cattle') {
        for (let i = 0; i < window.myData.farmCells.length; i++) {
            const col = window.myData.farmCells[i];
            for (let j = 0; j < col.length; j++) {
                const cell = col[j];
                if (cell[resourceType] > 0) {
                    cell[resourceType] -= 1;
                    updateFarm();
                    stop = true;
                    break;
                }
            }
            if (stop) {
                break;
            }
        }
    }

    updateResourceBar();
}

// 交换1小麦为1食物
function exchangeGrainForFood() {
    exchange('grain', 1);
}

// 交换1蔬菜为1食物
function exchangeVegetableForFood() {
    exchange('vegetable', 1);
}

//------------ 交换资源为分数
function exchangeResourcesForPoints(resourceType, thresholds, points) {
    // 计算玩家拥有的资源数量
    const resourceAmount = window.myData[resourceType];

    // 遍历阈值数组，找到对应的分数
    for (let i = thresholds.length - 1; i >= 0; i--) {
        if (resourceAmount >= thresholds[i]) {
            if (confirm(`将 ${thresholds[i]} ${TypeName[resourceType]} 兑换成 ${points[i]} 分`)) {
                window.myData.score += points[i]; // 增加玩家的分数
                window.myData[resourceType] -= thresholds[i];
                break;
            }
        }
    }

    updateResourceBar();
}

function exchangeResourcesForPointsBeforeFinalScore(resourceType, thresholds, points) {
    if (window.actionData.status != "beforeFinalScore") {
        customAlert("该分数兑换必须在终局计分前进行");
        return;
    }

    exchangeResourcesForPoints(resourceType, thresholds, points);
}

//------------ 烤面包
function bakeBread(resourceType, rate) {
    // 检查当前是否可以"烤面包"
    if (!hasSubstatus("bakeBread")) {
        alert("你的行动中必须包含'烤面包'字样才能烤面包！");
        return;
    }

    // 调用 exchange 函数进行资源兑换
    exchange(resourceType, rate);
}

//------------ 通用烤面包行动
async function startBakeBread() {
    // 等待烤面包操作完成
    await pushStatusAndWaitNewStatus(function () {
        // 修改状态为烤面包
        window.actionData.status = "bakeBread";
        window.actionData.substatus = ["bakeBread"];
        updateAdditionalView();
    });
}

async function endBakeBread() {
    popStatusOrEndAction();
}

//------------ 播种
function selectCellForSowing(x, y) {
    const cell = window.myData.farmCells[x][y];
    if (cell.building !== "field") {
        alert('请选择一个农田来播种。');
        return;
    }

    if (cell.grain > 0 || cell.vegetable > 0) {
        alert('这块农田中已有作物。');
        return;
    }

    showSowingSelectionDialog(function (selectedSeed) {
        if (selectedSeed === "grain" && window.myData.grain > 0) {
            cell.grain += 3;
            window.myData.grain -= 1;
        } else if (selectedSeed === "vegetable" && window.myData.vegetable > 0) {
            cell.vegetable += 2;
            window.myData.vegetable -= 1;
        } else {
            alert('你没有足够的种子来播种。');
            return;
        }
        updateFarm();
        updateResourceBar();
    });
}

function showSowingSelectionDialog(callback) {
    const seeds = ['grain', 'vegetable'];
    const seedNames = { grain: '小麦', vegetable: '蔬菜' };

    let availableSeeds = seeds.filter(seed => window.myData[seed] > 0).map(seed => ({
        value: seed,
        label: `${seedNames[seed]} (${window.myData[seed]})`
    }));

    if (availableSeeds.length === 0) {
        alert('你没有足够的种子来播种。');
        return;
    } 

    // 当 availableSeeds.length === 1，也依然弹出提示，使得用户确认使用当前仅剩的种子类型。

    showSelectionDialog('选择要播种的种子', availableSeeds, callback);
}

async function startSowingSeeds() {
    await pushStatusAndWaitNewStatus(async function () {
        window.actionData.status = "sowingSeeds";
        window.actionData.substatus = ["sowingSeeds"];
        updateAdditionalView();
    });
}

function endSowingSeeds() {
    popStatusOrEndAction();
}

//------------ 等待UI刷新完成的异步方法
async function waitForUIRefresh() {
    return new Promise((resolve) => {
        setTimeout(() => {
            resolve();
        }, 1); // 延迟1毫秒
    });
}